package cn.geminis.web.data;

import cn.geminis.core.data.query.FilterGroupCreator;
import cn.geminis.core.data.query.QueryParameters;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;
import java.util.Optional;

/**
 * @author Allen
 */
public interface FeignQueryService<T> {

    /**
     * 设置查询条件
     *
     * @param field       字段
     * @param compareType 比较方式
     * @param value       值
     * @return 服务对象
     */
    default FeignQueryService<T> where(String field, String compareType, Object value) {
        QueryParameters.instance().where(field, compareType, value);
        return this;
    }

    /**
     * 设置查询条件
     *
     * @param field 字段
     * @param value 值
     * @return 服务对象
     */
    default FeignQueryService<T> where(String field, Object value) {
        QueryParameters.instance().where(field, value);
        return this;
    }

    /**
     * 设置查询条件组
     *
     * @param type    组类型
     * @param creator 创建方法
     * @return 服务对象
     */
    default FeignQueryService<T> whereGroup(String type, FilterGroupCreator creator) {
        QueryParameters.instance().getFilterGroup().setType(type);
        creator.create(QueryParameters.instance().getFilterGroup());
        return this;
    }

    /**
     * 级联对象
     *
     * @param field 字段
     * @return 服务对象
     */
    default FeignQueryService<T> include(String field) {
        QueryParameters.instance().include(field);
        return this;
    }

    /**
     * 排序
     *
     * @param field 字段
     * @param order 顺序
     * @return 服务对象
     */
    default FeignQueryService<T> orderBy(String field, String order) {
        QueryParameters.instance().orderBy(field, order);
        return this;
    }

    /**
     * 排序
     *
     * @param field 字段
     * @return 服务对象
     */
    default FeignQueryService<T> orderBy(String field) {
        QueryParameters.instance().orderBy(field);
        return this;
    }

    /**
     * 分页页号
     *
     * @param pageIndex 页号
     * @return 服务对象
     */
    default FeignQueryService<T> pageIndex(int pageIndex) {
        QueryParameters.instance().setPageIndex(pageIndex);
        return this;
    }

    /**
     * 分页大小
     *
     * @param pageSize 大小
     * @return 服务对象
     */
    default FeignQueryService<T> pageSize(int pageSize) {
        QueryParameters.instance().setPageSize(pageSize);
        return this;
    }

    /**
     * 分页查询
     *
     * @return 分页查询结果
     */
    default Page<T> findPage() {
        try {
            return this.findPage(QueryParameters.instance());
        } finally {
            QueryParameters.clean();
        }
    }

    /**
     * 列表查询
     *
     * @return 查询列表
     */
    default List<T> findList() {
        try {
            return this.findList(QueryParameters.instance());
        } finally {
            QueryParameters.clean();
        }
    }

    /**
     * 单个查询
     *
     * @return 查询一个结果
     */
    default Optional<T> findOne() {
        try {
            return this.findOne(QueryParameters.instance());
        } finally {
            QueryParameters.clean();
        }
    }

    /**
     * 列表查询
     *
     * @param queryParameters 查询参数
     * @return 列表结果
     */
    default List<T> findList(@RequestBody final QueryParameters queryParameters) {
        queryParameters.setPageIndex(-1);
        return findPage(queryParameters).getContent();
    }

    /**
     * 查询一个数据
     *
     * @param queryParameters 查询参数
     * @return 查询结果
     */
    default Optional<T> findOne(@RequestBody final QueryParameters queryParameters) {
        queryParameters.setPageSize(1);
        var resultPage = findPage(queryParameters);
        return Optional.ofNullable(!resultPage.getContent().isEmpty() ? resultPage.getContent().get(0) : null);
    }


    /**
     * 查询分页数据
     *
     * @param queryParameters 查询参数
     * @return 查询结果
     */
    @PostMapping()
    Page<T> findPage(@RequestBody final QueryParameters queryParameters);
}
